package com.w.utils.thread.concurrent;
/**
 *
 **/

import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.IntStream;

/**
 * @Author weiwei
 * @Date 2020-11-26 16:05
 * @description 分段工具类
 **/
@Slf4j
public class SegmentationUtils {

    /**
     * 切分一个稽核分成一小段一小段
     *
     * @param list
     * @param count
     *
     * @return
     */
    public static <T> List<List<T>> segmentation(List<T> list, int count) {
        List<List<T>> result = new LinkedList<>();
        if (list != null) {
            int size = list.size();
            if (size > count) {
                for (int i = 0; i < size; i = i + count) {
                    if (i + count > size) {
                        result.add(list.subList(i, size));
                    } else {
                        result.add(list.subList(i, i + count));
                    }
                }
            } else {
                result.add(list);
            }
        }
        return result;
    }

    ;


    /**
     * @param list            要执行的数据
     * @param name            执行器名称
     * @param concurrentCount 开启的线程数
     * @param count           要执行的数据分段的个数
     * @param function        执行的参数
     * @param <T>
     *
     * @return
     */
    public static <T> int segmentationInvoker(List<T> list, String name, int concurrentCount, int count, ArgsInvoker function) {
        List<List<T>> segmentation = SegmentationUtils.segmentation(list, count);

        ConcurrentInvoker.Builder builder = new ConcurrentInvoker.Builder().withName(name).withConcurrentCount(concurrentCount);
        for (List<T> id: segmentation) {
            builder.withInvoker(id.get(0) + "", () -> function.invoke(id));
        }
        ConcurrentInvoker invoker = builder.build();
        AtomicInteger invokerRow = invoker.invoke(result -> {
            AtomicInteger row = new AtomicInteger();
            result.forEach((k, v) -> {
                row.addAndGet((int) v);
            });
            return row;
        });
        log.info("共执行了" + invokerRow + "条数据");
        return invokerRow.intValue();
    }


    public static void main(String[] args) {
        List<Integer> a = new LinkedList<>();
        IntStream.rangeClosed(1, 1000).forEach(a::add);
        System.out.println(a.size());
        segmentationInvoker(a, "test", 10, 499, (id) -> {
            log.info(String.valueOf(((List<Integer>) id[0]).get(0)));
            return 1;
        });
    }
}
